package com.sjz.controller;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.highgui.HighGui;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class OpenCvController {
	@Value("${opencv.image.path}")
	private String path;

	@RequestMapping("/sketch")
	public Object sketch(MultipartFile file) throws Exception {
		byte[] bytes = file.getBytes();
		// 使用前确保opencv库已加载,否则会报错
		MatOfByte matOfByte = new MatOfByte(bytes);
		Mat img = Imgcodecs.imdecode(matOfByte, Imgcodecs.IMREAD_COLOR);
		// 检查图像是否成功加载
		if (img.empty()) {
			throw new RuntimeException("读取图片失败");
		}
		// 灰度图片
		Mat gray = new Mat();
		Imgproc.cvtColor(img, gray, Imgproc.COLOR_BGR2GRAY);
		// 高斯去噪
		Mat blurredImage = new Mat();
		Imgproc.GaussianBlur(gray, blurredImage, new Size(21, 21), 0);
		// 融合原始灰度图像和模糊图像
		Mat sketchImage = new Mat();
		Core.divide(gray, blurredImage, sketchImage, 256.0);
		String filename = path + file.getOriginalFilename();
		// 保存图片
		Imgcodecs.imwrite(filename, sketchImage);
		return filename;
	}
	
	static {
		String opencvpath = System.getProperty("user.dir") + "\\src\\main\\resources\\lib\\";
		String opencvDllName = opencvpath + Core.NATIVE_LIBRARY_NAME + ".dll";
		System.out.println("opencvDllName:"+opencvDllName);
		System.load(opencvDllName);
		System.out.println("加载opencv动态库完成");
	 
	}

	/**
	 * 读取图片并显示
	 */
	public static void main(String[] args) {
		// readImage();
		//readCamera();
		// readFace();
		 
	}
	
	 
	
	/**
	 * 读取照片 并且把把人脸画图出来
	 */
	public static void readFace() {
		//CascadeClassifier类用于加载预训练的分类器，如Haar特征或LBP特征的级联分类器，通常用于人脸检测
		//需要读取一个文件，haarcascade_frontalface_default.xml
		 CascadeClassifier faceDetector = new CascadeClassifier("haarcascade_frontalface_default.xml");
	        Mat image = Imgcodecs.imread("input.jpg");
	        MatOfRect faceDetections = new MatOfRect();
	        faceDetector.detectMultiScale(image, faceDetections);

	        for (Rect rect : faceDetections.toArray()) {
	            Imgproc.rectangle(image, rect.tl(), rect.br(), new Scalar(0, 255, 0), 3);
	        }
	        Imgcodecs.imwrite("output.jpg", image); 
	}
	
	 
	
	
	/****
	 * 使用OpenCV的VideoCapture类来调用摄像头
	 */
	public static void readCamera() {
        // 打开默认摄像头（索引为0）
        VideoCapture capture = new VideoCapture(0);
        // 检查摄像头是否成功打开
        if (!capture.isOpened()) {
            System.out.println("无法打开摄像头。");
            return;
        }
        // 从摄像头读取并显示每一帧
        Mat frame = new Mat();
        while (capture.read(frame)) {
            // 显示图片 HighGui用户界面相关
            HighGui.imshow("Camera", frame);
            // 等待3毫秒 也就是每3毫秒从摄像头读取一帧
            int key = HighGui.waitKey(3);
            // 如果输入q 则释放资源
            if (key == 'q' || key == 'Q') {
                // 销毁所有窗口
                HighGui.destroyAllWindows();
                // 释放 VideoCapture 对象
                capture.release();
                System.exit(0);
                break;
            }

        }
        // 销毁所有窗口
        HighGui.destroyAllWindows();
        // 释放 VideoCapture 对象
        capture.release();
        System.exit(0);
	}
	
	
	/***
	 * 使用电脑摄像头抓拍照片
	 */
	public static void readCamera1() {
		// 打开摄像头
		VideoCapture camera = new VideoCapture(0);
		// 读取一帧图像
		Mat frame = new Mat();
		camera.read(frame);
		// 保存图像
		Imgcodecs.imwrite("photo1.jpg", frame);
		camera.release();
	}
	
	/***
	 * 加载指定的图片
	 */
	public static void readImage() {
				// 读取图片
				Mat img = Imgcodecs.imread("D:\\11\\audio\\4118014065.jpg");
				// 在hello窗口中显示图片
				HighGui.imshow("hello", img);
				// 等待按键 不设置设计会一直等待
				HighGui.waitKey();
				// 销毁所有窗口
				HighGui.destroyAllWindows();
				// 退出系统
				System.exit(0);
	}

}
